// 题目描述
// 给你字符串 s 和整数 k 。

// 请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。

// 英文中的 元音字母 为（a, e, i, o, u）。

 

// 示例 1：

// 输入：s = "abciiidef", k = 3
// 输出：3
// 解释：子字符串 "iii" 包含 3 个元音字母。
// 示例 2：

// 输入：s = "aeiou", k = 2
// 输出：2
// 解释：任意长度为 2 的子字符串都包含 2 个元音字母。
// 示例 3：

// 输入：s = "leetcode", k = 3
// 输出：2
// 解释："lee"、"eet" 和 "ode" 都包含 2 个元音字母。
// 示例 4：

// 输入：s = "rhythms", k = 4
// 输出：0
// 解释：字符串 s 中不含任何元音字母。
// 示例 5：

// 输入：s = "tryhard", k = 4
// 输出：1

// 自己的答案（能做出来，但超出了时间限制）：
/**
 * @param {string} s
 * @param {number} k
 * @return {number}
 */
var maxVowels = function(s, k) {
    let sum = s.substring(0, k);
    let maxSum = (sum.match(/[aeiouAEIOU]/g) || []).length;
    if(k === maxSum) {
        return maxSum;
    }

    // 使用滑动窗口计算每个窗口的和
    for (let i = k; i < s.length; i++) {
        sum = sum.substring(i - k) + s[i]; // 更新窗口的和
        if(/[aeiouAEIOU]/g.test(s[i])) {
            let sumCount =  (sum.match(/[aeiouAEIOU]/g) || []).length;
            if(k === sumCount) {
                return sumCount;
            }
            if (sumCount > maxSum) {
                maxSum = sumCount; // 更新最大和
            }
        }
    }

    // 计算并返回最大平均数
    return maxSum;
};

// 自己看答案后受启发修正版：
/**
 * @param {string} s
 * @param {number} k
 * @return {number}
 */
var maxVowels = function (s, k) {
    let sum = s.substring(0, k);
    let maxSum = (sum.match(/[aeiouAEIOU]/g) || []).length;
    let sumCount = maxSum
    if (k === maxSum) {
        return maxSum;
    }

    // 使用滑动窗口计算每个窗口的和
    for (let i = k; i < s.length; i++) {
        let curr = s[i],
            last = s[i - k];
        if (/[aeiouAEIOU]/g.test(curr)) sumCount++;
        if (/[aeiouAEIOU]/g.test(last)) sumCount--;
        maxSum = Math.max(sumCount, maxSum); // 更新最大和
        if (k === maxSum) {
            return maxSum;
        }
    }
    
    return maxSum;
};
console.log(maxVowels("abciiidef", 3))

// Gpt解法：
function maxVowels(s, k) {
    const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
    let maxVowelCount = 0;
    let currentVowelCount = 0;
 
    // 计算初始窗口中的元音字母数量
    for (let i = 0; i < k; i++) {
        if (vowels.has(s[i])) {
            currentVowelCount++;
        }
    }
    maxVowelCount = currentVowelCount;
 
    // 滑动窗口遍历字符串
    for (let i = k; i < s.length; i++) {
        if (vowels.has(s[i - k])) {
            currentVowelCount--;
        }
        if (vowels.has(s[i])) {
            currentVowelCount++;
        }
        maxVowelCount = Math.max(maxVowelCount, currentVowelCount);
    }
 
    return maxVowelCount;
}
 
// 示例测试
console.log(maxVowels("abciiidef", 3)); // 输出: 3
console.log(maxVowels("aeiou", 2)); // 输出: 2
console.log(maxVowels("leetcode", 3)); // 输出: 2
console.log(maxVowels("rhythms", 4)); // 输出: 0
console.log(maxVowels("tryhard", 4)); // 输出: 1

// 官方解法：
var maxVowels = function(s, k) {
    let vowel = 'aeiou', len = s.length, count = 0, max = 0, i = 0;
    
    for (; i < k; i++) {
      let curr = s.charAt(i);
      if (vowel.indexOf(curr) !== -1) count++;
    }
    max = Math.max(max, count);
    
    for (; i < len; i++) {
      let curr = s.charAt(i),
          last = s.charAt(i - k);
      if (vowel.indexOf(curr) !== -1) count++;
      if (vowel.indexOf(last) !== -1) count--;
      max = Math.max(count, max);
    }
    
    return max;
  };
